#include "nv_network.h"

nv_network::nv_network():QTcpServer(){
    delay_server=20000;
    client = new QTcpSocket(this);
}

nv_network::~nv_network(){}

bool nv_network::connect2Server(){
    blockSize=0;
    client->abort();
// conecta con Nodo Central (NC)

    QSettings settings("AIR", "SVE");
    if(!settings.contains("IP server") || !settings.contains("Port")){
        return false;
    }

    client->connectToHost(settings.value("IP server").toString(),settings.value("Port").toInt());

// envia el ID del dispositivo cliente y espera la respuesta del NC
    if(client->waitForConnected()){
        if(Client_ID())
            return true;
    }
    return false; //temporal
}

bool nv_network::Client_ID(){
    QSettings settings("AIR", "SVE");
    if(!settings.contains("IP local") || !settings.contains("pin")){
        return false;
    }

    string output;
    HMAC<SHA> h((const byte*)settings.value("pin").toString().toAscii().data(),settings.value("pin").toString().size());
    byte abMac[h.DIGESTSIZE];
    h.CalculateDigest(abMac,(const byte*)settings.value("IP local").toString().toAscii().data(),settings.value("IP local").toString().size());
    HexEncoder enc(new StringSink(output));
    enc.Put(abMac, h.DIGESTSIZE);
    enc.MessageEnd();

    msg_TX=QString::fromStdString(output);

    send_msg(msg_TX);
    if (!read_msg(msg_RX)){
        return false;}

    if(msg_RX.toInt()!=nv_network::hearing)
        return false;
    return true;
}

bool nv_network::read_msg(QString &msg){
    if(!client->isReadable()){
        return false;
    }

    while (client->bytesAvailable() < (int)sizeof(quint16)) {
        if (!client->waitForReadyRead(delay_server)) {
            return false;
        }
    }

    blockSize = 0;

    QDataStream in(client);
    in.setVersion(QDataStream::Qt_4_0);
    in >> blockSize;

    while (client->bytesAvailable() < blockSize) {
        if (!client->waitForReadyRead(delay_server)) {
            return false;
        }
    }

    in >> msg;
    in.~QDataStream();
    QObject::startTimer(50);
    return true;
}

void nv_network::send_msg(QString msg){
    QByteArray block;
    QDataStream out(&block, QIODevice::WriteOnly);
    out.setVersion(QDataStream::Qt_4_0);

    out << (quint16)0;
    out << msg;
    out.device()->seek(0);
    out << (quint16)(block.size() - sizeof(quint16));

    if(!client->isWritable()){
        return;
    }

    if(!client->isWritable()){
        return;
    }
    client->write(block);
}

QStringList nv_network::show_interfaces(){
    QList<QNetworkInterface> interfaces = QNetworkInterface::allInterfaces();
    QStringList str_interfaces;
    for(int i=0;i<interfaces.size();i++){
        str_interfaces << interfaces.at(i).name();
    }
    return str_interfaces;
}

QString nv_network::interface_IP(QString interface_name){
    QNetworkInterface interface(QNetworkInterface::interfaceFromName(interface_name));
    if(!interface.addressEntries().isEmpty())
        return interface.addressEntries().at(0).ip().toString();

    return QString();
}















